import mqtt, {
	log
} from 'mqtt/dist/mqtt';
import { createI18n } from 'vue-i18n';
import messages from './locale/index';

let i18nConfig = {
  locale: uni.getLocale(),// 获取已设置的语言
  messages
}
const i18n  = createI18n(i18nConfig);
const t = i18n.global.t;

class Mqtt {
	constructor() {
		this.pub_topic = '/wsq/device/';
		this.sub_topic = '/wsq/app/';
		this.url = null;
		this.imei = null;
		this.client = null;
		this.isConnected = false;
		this.timers = null;
		this.timerss = null;
		this.heartTimer = null; // 发送心跳定时器
		this.message = null;
		// 初始化事件监听器
		this.eventListeners = {};
	}
	init(connectedUrl='') {
		const url = connectedUrl || import.meta.env.VITE_SERVER_MQTT_BROKER;
		let that = this;
		if (that.client) {
			return;
		}
		
		if (that.isConnected) {
			that.end(function(){
				console.log('mqtt重新连接');
				that.connect(url);
			});
		}	
		
		console.log('mqtt开始连接');
		that.connect(url);
	}
	
	connect(url){		
		let that = this;
		uni.showLoading({
			title: t('mqtt.connecting'),
			mask: true
		});
		if (that.timerss) {
			clearTimeout(that.timerss);
			that.timerss = null;
		}
		// that.timerss = setTimeout(() => {
		// 	clearTimeout(that.timerss);
		// 	that.timerss = null;
		// 	that.client = null
		// }, 1000);
		setTimeout(() => {
			uni.hideLoading();
		}, 1000);
		
		that.url = url;
		let userdata = uni.getStorageSync("user")
		const options = {
			clean: true,
			connectTimeout: 2000,
			// clientId: 'clientid_dwq_' + (userdata.userid || Math.floor(Math.random()*10000)) + '_device_mqtt' + this.updateCurrentTime(),
			clientId: 'clientid_dwq_' + (userdata.userid || Math.floor(Math.random()*10000)),
			username: 'weishiqi',
			password: 'maxhom168',
			keepalive: 60
		};
		 
		that.client = mqtt.connect(this.url, options);
		this.initMore()
		// MQTT的Client对象自动会发送心跳
		// this.sendHeartbeat();
	}
	
	
	sendHeartbeat() {
		clearInterval(this.heartTimer);
		this.heartTimer = null;
	    const topic = 'heartbeat';
	    const message = 'online';
		// 40秒发送一个心跳包
		this.heartTimer = setInterval(()=>{
			this.client.publish(topic, message, (err) => {
			  if (err) {
			    console.error('发布心跳消息失败:', err);
				this.init(); // 重新连接
			  } else {
			    console.log('心跳消息发布成功');
			  }
			});
		}, 40000);	    
	}
	removeTopic(imei) {
		let subtop = this.sub_topic + String(imei).toUpperCase() + "/";
		console.log(`取消主题 ${subtop} 的订阅`);
		this.client.unsubscribe(subtop);
	}
	removeAllTopic(callBack) {
		let subtopAll = this.sub_topic + '#';		
		this.client.unsubscribe(subtopAll, function(err){
			if(err){
				console.warn(`取消全部主题 的订阅失败：`, err);
			}
			console.log(`取消全部主题 的订阅成功`);
			callBack&&callBack();
		});
	}
	addTopic(imei) {
		 
		if (!imei.imei) {
			return
		}
		if (imei.imei == this.imei) {
			return
		}
		
		// 重新订阅主题前 取消订阅之前的主题
		let that = this;
		this.imei = imei.imei;
		// this.initMore()
		let newsubtopic = that.sub_topic + String(imei.imei).toUpperCase() + "/";
		this.removeAllTopic(function(){
			console.log('订阅主题: ', newsubtopic)
			that.client.subscribe(newsubtopic, (err) => {
				if (!err) {
					if (that.timerss) {
						clearTimeout(that.timerss);
						that.timerss = null;
					}
					uni.showToast({
						title:  t('mqtt.subscripSuccess'),
						icon: 'none'
					});
					uni.hideLoading();
				} else {
					if (that.timerss) {
						clearTimeout(that.timerss);
						that.timerss = null;
					}
					uni.hideLoading();
					uni.showToast({
						title: t('mqtt.connectFail'),
						icon: 'none'
					});
				}
			});
		});			
	}
	hexStringToUint8Array(hex) {
		const length = hex.length / 2;
		const array = new Uint8Array(length);
		for (let i = 0; i < length; i++) {
			array[i] = parseInt(hex.substr(i * 2, 2), 16);
		}
		return array
	}
	uint8ArrayToHexString(array) {
		return Array.from(array)
			.map(byte => byte.toString(16).padStart(2, '0')) // 转为16进制并确保是两位数
			.join('');
	}
	decToHex(decNumber) {

		let str = Number(decNumber).toString(16).padStart(2, '0');
		//return str.length == 1 ? `0${str}` : str
		// 
		return str
	}
	//初始化监听交互
	initMore() {
		let that = this;
		console.log('初始化initMore')
		that.client.on('connect', () => {
			 
			that.isConnected = true;
		});
		that.client.on('error', (err) => {
			that.isConnected = false;
			that.client = null
		});
		that.client.on('pingresp', () => {
		    console.log('从mqtt服务器接收到心跳回复');
		    // 你可以在这里添加额外的逻辑，比如记录日志、更新连接状态等
		});
		that.client.on('pingreq', () => {
		    console.log('向mqtt服务器发送心跳');
		    // 你可以在这里添加额外的逻辑，比如记录日志、更新连接状态等
		});
		that.client.on('message', (topic, message) => {
			// uni.hideLoading();			
			if (that.timers) {
				clearTimeout(that.timers);
				that.timers = null;
			}
			
			console.log('接受主题', topic);
			if (topic === that.sub_topic + String(this.imei).toUpperCase() + "/") {
				if (message && message !== '' && message !== null) {
					if (Object.keys(message).length < 1) {
						uni.showToast({
							title: t('mqtt.successfully'),
							icon: 'success'
						});
						return;
					}
					try {
						let newStr = this.uint8ArrayToHexString(message)
						console.log('接受消息', newStr);
						if(newStr.startsWith('55aa8305')){
							// 喂食计划反馈成功
							return uni.$emit("weishiPlanSuccess",{});							
						}
						
						if(newStr.startsWith('55aaa4')){
							// 喂水器信息反馈
							return uni.$emit("resWaterInfo", newStr);
						}
						
						if(newStr.startsWith('55aaa2')){
							// 喂水器模式切换 反馈
							return uni.$emit("resWaterModel", newStr);
						}
						
						if(newStr.startsWith('55aaa1')){
							// 喂水器开关切换 反馈
							return uni.$emit("resWaterOpenChange", newStr);
						}
						
					} catch (error) {
						console.error('JSON parsing error:', error);
						uni.showToast({
							title: t('mqtt.msgFormatError'),
							icon: 'error'
						});
					}
				} else {
					uni.showToast({
						title: t('mqtt.msgInvalid'),
						icon: 'error'
					});
				}
			}
		});
		that.client.on('reconnect', () => {
			 
		});
	}
	updateCurrentTime() {
		const now = new Date();
		const year = now.getFullYear();
		const month = (now.getMonth() + 1).toString().padStart(2, '0');
		const day = now.getDate().toString().padStart(2, '0');
		const hours = now.getHours().toString().padStart(2, '0');
		const minutes = now.getMinutes().toString().padStart(2, '0');
		return `${year}${month}${day}${hours}${minutes}`;
	}
	end(callback) {
		this.client && this.client.end(true, {}, function(){
			callback();
		});
		clearInterval(this.heartTimer);
	}

	weishishijian(params) { // 喂食计划
		 
		let str =
			`55aa0305${this.decToHex(params.fenzuid)}${this.decToHex(params.on)}${this.decToHex(params.fenshu)}${this.decToHex(params.xiaoshi)}${this.decToHex(params.fenzhong)}`

		//55aa 0305 0000 b161 21ba 
		 
		let num = 0
		for (let i = 0; i < str.length; i += 2) {
			let decimalNumber = parseInt(`${str[i]}${str[i+1]}`, 16);
			num += decimalNumber
		}
		num = num % 256
		 
		let code = this.decToHex(num)
		let newStr = `${str}${code}ab`
		let query = this.hexStringToUint8Array(newStr)
		 
		this.sendMessage(query);
		// 重复发送报文： 重复3次，每次间隔10秒
		let maxCount = 3;
		let repeatTimer = setInterval(()=>{
			maxCount--;
			if(maxCount>=0){
				console.log('重复发送喂食计划')
				this.sendMessage(query);				
			}else{
				clearInterval(repeatTimer);
				uni.$emit('weishiPlanError',{});
			}
		},10000);
		uni.$on("weishiPlanSuccess",()=>{
			console.log('取消 重复发送喂食计划')
			clearInterval(repeatTimer);
		});
	}
	weishi(params) { // 立即喂食
		console.log('立即喂食：', params);
		let str = `55aa020200${this.decToHex(params)}`
		let num = 0
		for (let i = 0; i < str.length; i += 2) {
			let decimalNumber = parseInt(`${str[i]}${str[i+1]}`, 16);
			num += decimalNumber
		}
		num = num - 256
		let code = this.decToHex(num)
		let newStr = `${str}${code}ab`
		let query = this.hexStringToUint8Array(newStr)
		 
		this.sendMessage(query)
	}
	
	// 获取 喂水器的电量和水量信息
	waterInfo() { 
		console.log('获取 喂水器的电量 水量、模式和开关信息：');
		let str = `55aa24050000000000`;
		this.waterMessageDecode(str);
	}
	// 喂水器模式切换: 0-间歇模式, 1-雷达模式
	waterModelChange(model){
		console.log('喂水器模式切换, 切换模式为: ', model);
		let str = `55aa22010${model}`
		this.waterMessageDecode(str);
	}
	// 喂水器开关切换: 0-停止出水, 1-开始出水
	waterOpenStatusChange(open=false){
		const openNum = open? 1: 0;
		let str = `55aa21010${openNum}`
		console.log('喂水器开关切换: ', str);
		this.waterMessageDecode(str);
	}
			
	// 喂水器信息编码
	waterMessageDecode(str){
		if(!str){
			console.warn('喂水器信息编码,原始字符串不得为空')
			return;
		}
		let num = 0
		for (let i = 0; i < str.length; i += 2) {
			let decimalNumber = parseInt(`${str[i]}${str[i+1]}`, 16);
			num += decimalNumber
		}
		num = num - 256
		let code = this.decToHex(num)
		let newStr = `${str}${code}ab`
		let query = this.hexStringToUint8Array(newStr)
		// console.log('newStr= ', newStr, '; query = ', query);
		this.sendMessage(query)
	}
	
	xym(str) {
		let num = 0
		for (let i = 0; i < str.length; i += 2) {
			let decimalNumber = parseInt(`${str[i]}${str[i+1]}`, 16);
			num += decimalNumber
		}
		num = num - 256
		let code = this.decToHex(num)
		return code;
	}
	delcmd(params) { // 立即喂食
		let str = `55aa11020001`
		let code = this.xym(str);
		 
		let newStr = `${str}${code}ab`
		let query = this.hexStringToUint8Array(newStr)
		 
		this.sendMessage(query)
	}	
	sendMessage(messages) {
		let that = this;
		if (!that.client) {
			 console.log('重新连接')
			uni.$emit('chongxinlianjie');
			return;
		}

		if (that.timers) {
			clearTimeout(that.timers);
			that.timers = null;
		}

		if (!this.imei) {
			uni.showToast({
				title: t('mqtt.deviceNotConected'),
				icon: 'none'
			})			 
			return
		}
		
		let newpubtopic = that.pub_topic + this.imei.toUpperCase() + "/";
		that.client.publish(newpubtopic, messages);
		 
		if (that.client.connected && that.client.stream._readableState.pipesCount && !that.client.stream
			._readableState.destroyed) {} else {
			 
			this.client = null
			that.client = null
			that.init()
			 
			if (that.client) {
				 
				that.client.publish(newpubtopic, messages);
			}
		}


	}
}

export {
	Mqtt
};